package com.jy.rhin.domain.document.filter.impl;

import com.jy.rhin.domain.document.filter.DocumentFilter;
import com.jy.rhin.domain.document.filter.DocumentFilterDescEnum;
import com.jy.rhin.domain.exception.RhinInfraErrorType;
import com.jy.rhin.infra.uitl.Asserts;
import com.jy.rhin.sdk.dto.document.DocumentContentDto;
import com.jy.rhin.sdk.dto.document.DocumentEntryDto;
import com.jy.rhin.sdk.dto.document.DocumentFolderDto;
import com.jy.rhin.sdk.dto.document.DocumentSubmissionSetDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author dhl
 * @date 2022/6/2
 * @Description uniqueId不重复验证
 */
@Slf4j
@Service
public class DocumentFilter4UniqueIdValid implements DocumentFilter {
    @Override
    public boolean shouldFilter(DocumentSubmissionSetDto submissionSet, List<DocumentContentDto> contentList) {
        return true;
    }

    /**
     * 在一个提交集中，documents节点下所有id不重复；entry节点下所有id/uniqueId不重复；folder节点下所有id/uniqueId不重复
     *
     * @param submissionSet
     * @param contentList
     */
    @Override
    public void doFilter(DocumentSubmissionSetDto submissionSet, List<DocumentContentDto> contentList) {
        //documents节点下所有id不重复
        Asserts.isFalse(hasRepeatEle(contentList, DocumentContentDto::getId), RhinInfraErrorType.UNIQUE_ID_REPEAT);
        List<DocumentEntryDto> entries = submissionSet.getEntries();
        //entry节点下所有id不重复
        Asserts.isFalse(hasRepeatEle(entries, DocumentEntryDto::getId), RhinInfraErrorType.UNIQUE_ID_REPEAT);
        //entry节点下所有uniqueId不重复
        Asserts.isFalse(hasRepeatEle(entries, DocumentEntryDto::getUniqueId), RhinInfraErrorType.UNIQUE_ID_REPEAT);
        List<DocumentFolderDto> folders = submissionSet.getFolders();
        //folder节点下所有id不重复
        Asserts.isFalse(hasRepeatEle(folders, DocumentFolderDto::getId), RhinInfraErrorType.UNIQUE_ID_REPEAT);
        //folder节点下所有uniqueId不重复
        Asserts.isFalse(hasRepeatEle(folders, DocumentFolderDto::getUniqueId), RhinInfraErrorType.UNIQUE_ID_REPEAT);
    }

    /**
     * 验证集合中是否有重复的元素
     *
     * @param list 待验证的集合
     * @param key  重复验证的key
     * @param <T>
     * @return
     */
    private <T> boolean hasRepeatEle(List<T> list, Function<T, String> key) {
        if (CollectionUtils.isEmpty(list)) {
            return false;
        }
        Set<String> keySet = list.stream().map(key).collect(Collectors.toSet());
        return keySet.size() != list.size();
    }

    @Override
    public DocumentFilterDescEnum filterDesc() {
        return DocumentFilterDescEnum.UNIQUE_ID_NOT_REPEAT;
    }
}
